import json
import re
import sqlite3
import urllib.request as urllib
import time
import colorful
import requests
import tableprint as tp
import random
from consolemenu import *
from consolemenu.format import *
from consolemenu.items import *
from pyquery import PyQuery as pq
from xpinyin import Pinyin

USERNAME = "Pay6262"

PASSWORD = "z123456"

VIDEO = "http://www.uuse444.com/videos/{0}"

DOMAIN = "http://www.uuse444.com{0}"

PAGE = "http://www.uuse444.com/videos/{0}?page={1}"

SESSION = requests.session()

COOKIE = {"AVS": "p0n2ciort8n2nri6guub04pa34", "SL_GWPT_Show_Hide_tmp": "1",
          "SL_wptGlobTipTmp": "1", "__51cke__": "", "__51laig__": "52",
          "__tins__194141237": "%7B%22sid%22%3A%201568031162670%2C%20%22vd%22%3A%203%2C%20%22expires%22%3A%201568033238787%7D"}
SESSION.headers = {
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/76.0.3809.132 Safari/537.36",
    'Upgrade-Insecure-Requests': '1',
    'Cookie': str(COOKIE),
    'Referer': 'http://www.uuse444.com/',
    'Host': 'www.uuse444.com',
    'Accept-Encoding': 'gizp,defale',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive'
}
TYPE_HEADER = ["ID", "NAME", "T_ID"]

M3U8_RE = "(http.*?m3u8)"

COOKIE_FILE = "Cookies.json"

# 404BBB
BBS_USERNAME = "hk8888"
BBS_PASSWORD = "qq888999"
BBS_SESSION = requests.session()
BBS_Modules = {
    "自拍": "http://www.404bbb.com/forum.php?mod=post&action=newthread&fid=43&extra=&topicsubmit=yes",
    "日韩": "http://www.404bbb.com/forum.php?mod=post&action=newthread&fid=44&extra=&topicsubmit=yes",
    "欧美": "http://www.404bbb.com/forum.php?mod=post&action=newthread&fid=45&extra=&topicsubmit=yes",
    "动漫": "http://www.404bbb.com/forum.php?mod=post&action=newthread&fid=46&extra=&topicsubmit=yes",
}

SQL_FILE = "98k.sql"


class DB(object):
    def __init__(self):
        self.conn = sqlite3.connect('uuse222.db', check_same_thread=False)
        self.cursor = self.conn.cursor()
        pass

    def insertType(self, t_name, t_id):
        sql = "insert into type (type_name, type_t_id) VALUES('{0}',{1})".format(t_name, t_id)
        self.cursor.execute(sql)
        self.conn.commit()
        return self.cursor.rowcount == 1

    def queryAllType(self):
        sql = "select * from type"
        self.cursor.execute(sql)
        return self.cursor.fetchall()

    def queryTypeById(self, t_id):
        sql = "select * from type where type_id = {0}".format(t_id)
        self.cursor.execute(sql)
        return self.cursor.fetchall()[0]

    def queryVideoByHref(self, v_href):
        sql = "select count(*) from video where video_href like '%{0}%'".format(v_href)
        print(sql)
        self.cursor.execute(sql)
        return self.cursor.fetchall()[0][0]

    def insertVideo(self, v_title, v_type, v_m3u8, v_img, v_href):
        sql = "insert into video (video_title, video_type, video_m3u8, video_img, video_href) VALUES ('{0}','{1}'," \
              "'{2}','{3}','{4}') ".format(v_title.replace("'", ""), v_type, v_m3u8, v_img, v_href)
        print(colorful.cyan | sql)
        self.cursor.execute(sql)
        self.conn.commit()
        return self.cursor.rowcount

    def queryAllVideo(self):
        sql = "select video_id,video_title, video_type, video_m3u8, video_img, video_href from video where " \
              "video_is_syn= 0"
        self.cursor.execute(sql)
        return self.cursor.fetchall()

    def queryAllVideoGen(self):
        sql = "select video_id,video_title, video_type, video_m3u8, video_img, video_href from video where " \
              "video_is_gen= 0"
        self.cursor.execute(sql)
        return self.cursor.fetchall()

    def updateVideoStatus(self, v_id):
        sql = "UPDATE video SET video_is_syn = 1 WHERE video_id = '{0}'".format(v_id)
        self.cursor.execute(sql)
        self.conn.commit()
        return self.cursor.rowcount == 1

    def updateVideoGen(self, v_id):
        sql = "UPDATE video SET video_is_gen = 1 WHERE video_id = '{0}'".format(v_id)
        self.cursor.execute(sql)
        self.conn.commit()
        return self.cursor.rowcount == 1

    def queryVideoByType(self, t_id):
        sql = "select * from video where video_type = '{0}'".format(t_id)
        self.cursor.execute(sql)
        return self.cursor.fetchall()


def serialize_cookies():
    """
    保存cookies至本地
    """
    cookies_dict = requests.utils.dict_from_cookiejar(SESSION.cookies)
    COOKIE.update(cookies_dict)
    with open(COOKIE_FILE, 'w+', encoding='utf-8') as file:
        json.dump(COOKIE, file)
        print(colorful.cyan('保存cookies文件成功！文件名: %s' % COOKIE_FILE))


def deserialize_cookies():
    """
    读取本地cookies
    """
    with open(COOKIE_FILE, 'r+', encoding='utf-8') as file:
        cookies_dict = json.load(file)
        cookies = requests.utils.cookiejar_from_dict(cookies_dict)
        return cookies


class YellowWeb:
    def __init__(self):
        self.username = USERNAME
        self.password = PASSWORD
        pass

    def login(self):
        response = SESSION.post("http://www.uuse444.com/login",
                                data={"username": self.username, "password": self.password, "login_remember": "on",
                                      "submit_login": ""}, allow_redirects=True)
        response.encoding = "utf-8"
        serialize_cookies()
        SESSION.cookies = deserialize_cookies()
        index = SESSION.get("http://www.uuse444.com/index.php")
        index.encoding = "utf-8"
        del SESSION.headers["Cookie"]
        return response.text.find(self.username)


def AddType():
    t_name = input("名称 : ")
    t_id = input("类别 : ")
    if db.insertType(t_name, t_id):
        print(colorful.green | "添加成功")
    else:
        print(colorful.red | "添加失败")
    Screen().input('Press [Enter] to continue')
    pass


def Search():
    pass


def getVideos(doc):
    videos = doc("div[class='well well-sm']")
    del videos[0]
    return videos


def getPageCount(doc):
    return pq(doc("li[class='hidden-xs']")[-1]).text()


def ScanAll():
    tp.table(db.queryAllType(), TYPE_HEADER, style="fancy_grid")
    types = db.queryAllType()
    for t in types:
        flag = input("是否扫描{0}?(y/n) : ".format(t[1]))
        if not flag == 'y':
            types.remove(t)
        else:
            print("{0}进入队列".format(t[1]))

    print("扫描队列 : ")
    tp.table(db.queryAllType(), TYPE_HEADER, style="fancy_grid")
    for t in types:
        print("扫描队列 : ")
        tp.table(db.queryAllType(), TYPE_HEADER, style="fancy_grid")
        Scan(t, )
    Screen().input('Press [Enter] to continue')
    pass


def ScanByType():
    SESSION.cookies = deserialize_cookies()
    tp.table(db.queryAllType(), TYPE_HEADER, style="fancy_grid")
    key = input("输入主键开始扫描 : ")
    startPage = input("输入开始页数(不填从1开始) : ")
    if startPage == "":
        startPage = 12
    type_ = db.queryTypeById(key)
    Scan(type_, startPage)
    Screen().input('Press [Enter] to continue')


def Scan(type_, startPage=1):
    try:
        response = SESSION.get(VIDEO.format(type_[2]))
        response.encoding = "utf-8"
        doc = pq(response.text)
        pageCount = getPageCount(doc)
        for i in range(int(startPage), int(pageCount)):
            print("----------------------------------开始扫描第{0}页-------------------------------".format(i))
            v_doc = SESSION.get(PAGE.format(type_[2], i))
            v_doc.encoding = "utf-8"
            for v in getVideos(pq(v_doc.text)).items():
                print("-----------------------START----------------------")
                title = v("img").attr("title")
                href = v("a").attr("href")
                img_href = v("img").attr("src")
                print("标题 :", title)
                print("链接 : ", href)
                print("图片 : ", img_href)
                response = SESSION.get(DOMAIN.format(urllib.quote(v("a").attr("href"))))
                response.encoding = "utf-8"
                m3u8 = re.findall(M3U8_RE, response.text)[0]
                print("M3U8 : ", m3u8)
                if db.queryVideoByHref(href) == 0:
                    db.insertVideo(title, type_[2], m3u8, img_href, str(DOMAIN.format(href)))
                else:
                    print(colorful.red | title, " 已存在")
                print("-----------------------END----------------------")
            print("----------------------------------剩余{0}页--------------------------------".format(int(pageCount) - i))
    except IndexError:
        print(colorful.red | "主键错误！")


def SynchronizedBBS():
    def sendPost(url, subject, message):

        BBS_SESSION.cookies.set("Tu7u_2132_auth",
                                "12ae%2F%2BwPucdvQaT3NQ5brZKKlYcrgOB%2BRPdn4OwSUDGjTNv75v"
                                "%2FrQ9LEYrhYbJrx3lYkdiDDBYCPX8ogx4aH")
        BBS_SESSION.cookies.set("Tu7u_2132_saltkey", "bP1aM4fp")
        data = {
            'formhash': "e25dec15",
            'posttime': '1568185793',
            'wysiwyg': '1',
            'subject': subject,
            'message': message,
            'romotepic': '1',
            'replycredit_extcredits': '0',
            'replycredit_times': '1',
            'replycredit_membertimes': '1',
            'replycredit_random': '100',
            'usesig': '1'
        }
        response = BBS_SESSION.post(
            url, data=data).text

        if pq(response)("title").text().find(subject) == 0:
            print(colorful.green | "论坛 : {0} 发送成功！".format(subject))
        else:
            print(colorful.red | "论坛 : {0} 发送失败！".format(subject))
            print(colorful.red | "原因 ：{0}".format(response))

    def getContent(img, m3u8):
        return "[img]{0}[/img][hide][ck]{1}[/ck][/hide]".format(img, m3u8)

    for video in db.queryAllVideo():
        if video[2] == 1:
            sendPost(BBS_Modules["日韩"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 日韩 板块".format(video[1][0:40]))
        elif video[2] == 2:
            sendPost(BBS_Modules["日韩"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 日韩 板块".format(video[1][0:40]))
        elif video[2] == 3:
            sendPost(BBS_Modules["日韩"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 日韩 板块".format(video[1][0:40]))
        elif video[2] == 4:
            sendPost(BBS_Modules["欧美"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 欧美 板块".format(video[1][0:40]))
        elif video[2] == 5:
            sendPost(BBS_Modules["动漫"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 动漫 板块".format(video[1][0:40]))
        elif video[2] == 6:
            sendPost(BBS_Modules["自拍"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 自拍 板块".format(video[1][0:40]))
        elif video[2] == 7:
            sendPost(BBS_Modules["日韩"], video[1][0:40], getContent(video[4], video[3]))
            print(colorful.cyan | "正在同步 : {0} 至 日韩 板块".format(video[1][0:40]))
        else:
            pass
        db.updateVideoStatus(video[0])
    Screen().input('Press [Enter] to continue')


def GenerateSql98K():
    pin = Pinyin()
    temp_sql = "`mac_vod`(`vod_id`, `type_id`, `type_id_1`, `group_id`, `vod_name`, `vod_sub`, `vod_en`, `vod_status`, " \
               "`vod_letter`, `vod_color`, `vod_tag`, `vod_class`, `vod_pic`, `vod_pic_thumb`, `vod_pic_slide`, " \
               "`vod_actor`, `vod_director`, `vod_writer`, `vod_behind`, `vod_blurb`, `vod_remarks`, " \
               "`vod_pubdate`, `vod_total`, `vod_serial`, `vod_tv`, `vod_weekday`, `vod_area`, " \
               "`vod_lang`, `vod_year`, `vod_version`, `vod_state`, `vod_author`, `vod_jumpurl`, " \
               "`vod_tpl`, `vod_tpl_play`, `vod_tpl_down`, `vod_isend`, `vod_lock`, " \
               "`vod_level`, `vod_copyright`, `vod_points`, `vod_points_play`, " \
               "`vod_points_down`, `vod_hits`, `vod_hits_day`, `vod_hits_week`, " \
               "`vod_hits_month`, `vod_duration`, `vod_up`, `vod_down`, `vod_score`, `vod_score_all`, " \
               "`vod_score_num`, `vod_time`, `vod_time_add`, `vod_time_hits`, `vod_time_make`, `vod_trysee`, " \
               "`vod_douban_id`, `vod_douban_score`, `vod_reurl`, `vod_rel_vod`, `vod_rel_art`, `vod_pwd`, " \
               "`vod_pwd_url`, `vod_pwd_play`, `vod_pwd_play_url`, `vod_pwd_down`, `vod_pwd_down_url`, `vod_content`, " \
               "`vod_play_from`, `vod_play_server`, `vod_play_note`, `vod_play_url`, `vod_down_from`, " \
               "`vod_down_server`, `vod_down_note`, `vod_down_url`) VALUES (0,{0},0,0," \
               "'{1}','','{2}','1','{3}','','','javhd','{4}'," \
               "'{5}','','','','','','','',{6}," \
               "1,1,'','','','','2019','',''," \
               "'','','','','l',1,0,0,0," \
               "0,0,0,{7},{8},{9},{10},'00:00:00',{11}," \
               "{12},0.0,0,{13},{14},{15},16,0,0," \
               "0,0.0,'','','','','','',''," \
               "'','','{16}','dplayer','','','{17}','',''," \
               "'','') "

    print("关联匹配 :")
    tp.table(db.queryAllType(), TYPE_HEADER, style="fancy_grid")
    newTypes = []
    for item in db.queryAllType():
        print(colorful.cyan | "本地分类：{0} 对应 98K 分类(ID) : ".format(item[1]))
        origin_type = input("")
        newType = {"local": item[0], "origin": origin_type}
        newTypes.append(newType)
    with open(SQL_FILE, 'w+', encoding='utf-8') as file:
        for t in newTypes:
            for v in db.queryVideoByType(t['local']):
                print(colorful.cyan | "-------------------------------------------------------------------------------")
                sql = "INSERT INTO " + temp_sql.format(t['origin'], v[1], pin.get_pinyin(v[1], ""),
                                                       pin.get_pinyin(v[1], "")[0].upper(),
                                                       v[4], v[4], '2019-09-12', random.randint(0, 1000),
                                                       random.randint(0, 1000),
                                                       random.randint(0, 1000), random.randint(0, 1000),
                                                       random.randint(0, 1000),
                                                       random.randint(0, 1000),
                                                       int(time.time()), int(time.time()), int(time.time()), v[1],
                                                       v[3]) + "\n"
                print(sql)
                file.write(sql)
                print(colorful.cyan | "-------------------------------------------------------------------------------")
                print(colorful.cyan | "-------------------------------------------------------------------------------")
        print(colorful.green | "完成!")
        Screen().input('Press [Enter] to continue')
        file.close()


def EnterMenu():
    menu_format = MenuFormatBuilder().set_border_style_type(MenuBorderStyleType.HEAVY_BORDER) \
        .set_prompt("SELECT>") \
        .set_title_align('center') \
        .set_subtitle_align('center') \
        .set_left_margin(4) \
        .set_right_margin(4) \
        .show_header_bottom_border(True)

    menu = ConsoleMenu("WWW.UUSE222.COM", "THIS IS COMMANDLINE SHELL MENU , CLICK ENTER", formatter=menu_format)
    # Create some items

    # MenuItem is the base class for all items, it doesn't do anything when selected
    menu_item = FunctionItem("扫描(全部)", ScanAll)

    # A FunctionItem runs a Python function when selected
    function_item = FunctionItem("扫描(类型)", ScanByType)

    # A CommandItem runs a console command
    command_item = FunctionItem("生成98K SQL", GenerateSql98K)

    # A SelectionMenu constructs a menu from a list of strings
    # selection_menu = SelectionMenu(["404BBB", "98K", "N/A"])
    syn_bbs = FunctionItem("SYN 404BBS", SynchronizedBBS)

    syn_mgr_sub = ConsoleMenu("WWW.UUSE222.COM", "SYNCHRONIZED MENU , CLICK ENTER")
    syn_mgr_sub.append_item(syn_bbs)
    # A SubmenuItem lets you add a menu (the selection_menu above, for example)
    # as a submenu of another menu
    submenu_item = SubmenuItem("同步", syn_mgr_sub, menu)

    add_type_item = FunctionItem("添加UUSE222菜單類型", AddType)
    query_video = FunctionItem("SEARCH ALL VIDEO", Search)

    db_mgr_sub = ConsoleMenu("WWW.UUSE222.COM", "THIS IS COMMANDLINE SHELL MENU , CLICK ENTER")
    db_mgr_sub.append_item(add_type_item)
    db_mgr_sub.append_item(query_video)
    db_mgr_item = SubmenuItem("数据库管理", db_mgr_sub, menu)
    # Once we're done creating them, we just add the items to the menu
    menu.append_item(menu_item)
    menu.append_item(function_item)
    menu.append_item(command_item)
    menu.append_item(submenu_item)
    menu.append_item(db_mgr_item)
    # Finally, we call show to show the menu and allow the user to interact
    menu.show()


if __name__ == '__main__':
    db = DB()
    yellowWeb = YellowWeb()
    if yellowWeb.login():
        print(colorful.green | "Login Success !")
        EnterMenu()
    else:
        print(colorful.red | "Login Error !")
